package com.zdkj.subway.check.service.impl.subwayRat.TVMRevenueVarianceAudit.TvmChaYiDXC.tvmCengJiCYXC.tvmXianJinCengJiCYDXC;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.zdkj.subway.check.dto.SwAuInternetTicketEquipmentDto;
import com.zdkj.subway.check.entity.SwAuInternetTicketEquipment;
import com.zdkj.subway.check.entity.SwAuItvmOnlineAmountHierarchyDifference;
import com.zdkj.subway.check.entity.SwAuTvmCashAmountHierarchyDifference;
import com.zdkj.subway.check.mapper.*;
import com.zdkj.subway.check.util.DateFormat;
import com.zdkj.subway.check.util.LocalDateConverter;
import com.zdkj.subway.check.util.LocalDateTimeConverter;
import com.zdkj.subway.check.util.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * TVM现金层级差异待协查
 */
@Service
@Slf4j
public class TvmXianJinCengJiCYDXCService {

    @Resource
    private SwAuTvmMoneyAssistMapper swAuTvmMoneyAssistMapper;
    @Resource
    private SwAuTvmSingleAssistMapper swAuTvmSingleAssistMapper;
    @Resource
    private SwAuTvmDailyBillAssistMapper swAuTvmDailyBillAssistMapper;
    @Resource
    private SwAuTvmDailyBillAssistDetailMapper swAuTvmDailyBillAssistDetailMapper;
    @Resource
    private SwAuTvmCashAmountHierarchyDifferenceMapper swIfTxnTicketTransactionStatisticsMapper;
    @Resource
    private SwAuTvmCashboxAmountHierarchyDifferenceMapper swAuTvmCashboxAmountHierarchyDifferenceMapper;
    @Resource
    private SwAuItvmOnlineAmountHierarchyDifferenceMapper swAuItvmOnlineAmountHierarchyDifferenceMapper;
    @Resource
    private SwAuInternetTicketEquipmentMapper swAuInternetTicketEquipmentMapper;
    @Resource
    private SwPmDeviceOperationCodeMapper swPmDeviceOperationCodeMapper;
    @Resource
    private SwAuInternetTicketEquipmentDetailsMapper swAuInternetTicketEquipmentDetailsMapper;
    @Resource
    private TvmXianJinCengJiCYDXCService tvmXianJinCengJiCYDXCService;

    /**
     * 结账单据与SC层级差异待协查
     * @param swIfTxnTicketTransactionStatistics
     * @return
     */
    public List<Map<String, Object>> getSwAuTvmCashAmountHierarchyDifferenceList(SwAuTvmCashAmountHierarchyDifference swIfTxnTicketTransactionStatistics) {
        List<Map<String, Object>> res= swIfTxnTicketTransactionStatisticsMapper.getSwAuTvmCashAmountHierarchyDifferenceList(swIfTxnTicketTransactionStatistics);
        return res;
    }

    /**
     * 分钱箱
     * @param param
     * @return
     */
    public List<Map<String, Object>> getSwAuTvmCashboxAmountHierarchyDifferenceList(Map<String,String> param) {
//        HashMap req = JSONObject.parseObject(JSONObject.toJSONString(swAuTvmCashboxAmountHierarchyDifference), HashMap.class);
        List<Map<String, Object>> res = swAuTvmCashboxAmountHierarchyDifferenceMapper.getSwAuTvmCashboxAmountHierarchyDifferenceList(param);
        return res;
    }

    /**
     * itvm
     * @param swAuItvmOnlineAmountHierarchyDifference
     * @return
     */
    public List<Map<String, Object>> getSwAuItvmOnlineAmountHierarchyDifferenceList(SwAuItvmOnlineAmountHierarchyDifference swAuItvmOnlineAmountHierarchyDifference) {
        List<Map<String, Object>> res = swAuItvmOnlineAmountHierarchyDifferenceMapper.getSwAuItvmOnlineAmountHierarchyDifferenceList(swAuItvmOnlineAmountHierarchyDifference);
        return res;
    }

    /**
     * 互联网售票机数据录入
     * @param swAuInternetTicketEquipment
     * @return
     */
    public List<Map<String, Object>> getSwAuInputInternetTicketEquipmentList(SwAuInternetTicketEquipment swAuInternetTicketEquipment) {
        List<Map<String, Object>> res = swAuInternetTicketEquipmentMapper.getSwAuInputInternetTicketEquipmentList(swAuInternetTicketEquipment);
        return res;
    }

    /**
     * 互联网售票机数据录入 导出
     * @param ids
     * @return
     */
    public List<Map<String, Object>> getSwAuInputInternetTicketEquipmentIdsList(String[] ids) {
        List<Map<String, Object>> res = swAuInternetTicketEquipmentMapper.getSwAuInputInternetTicketEquipmentIdsList(ids);
        return res;
    }

    /**
     * 修改或者添加数据
     * @param swAuInternetTicketEquipment
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Integer mondifySwAuInputInternetTicketEquipmentDetail(String detailStr,SwAuInternetTicketEquipment swAuInternetTicketEquipment) throws Exception {
        try{
//            JSONArray details=JSONArray.parseArray(detailStr);
//            if(swAuInternetTicketEquipmentDetails.getId()!=null){ //修改
//                //2-2-13、888互联网售票机明细表 SW_AU_INTERNET_TICKET_EQUIPMENT_DETAILS
//                swAuInternetTicketEquipmentDetails.setUpdateTime(new Date());
//                    int ins= swAuInternetTicketEquipmentMapper.updateById(swAuInternetTicketEquipmentDetails);
//            }else if(swAuInternetTicketEquipmentDetails.getId()==null){
//                //2-2-13、888互联网售票机明细表 SW_AU_INTERNET_TICKET_EQUIPMENT_DETAILS
//                for(int i=0;i<details.size();i++){
//                    JSONObject jsonObject = details.getJSONObject(i);
//                    SwAuInternetTicketEquipmentDetails s = JSONObject.parseObject(jsonObject.toJSONString(), SwAuInternetTicketEquipmentDetails.class);
////                    SwPmDeviceOperationCode equipmentId = swPmDeviceOperationCodeMapper.getSwPmDeviceOperationCodeById(jsonObject.getInteger("equipmentId"));
//                    s.setCreatorId(UserInfo.getId());
//                    s.setCreatorName(UserInfo.getUserName());
//                    s.setDelFlag("0");
//                    s.setStaticDate(swAuInternetTicketEquipmentDetails.getStaticDate());
//                    s.setLineCode(swAuInternetTicketEquipmentDetails.getLineCode());
//                    s.setStationCode(swAuInternetTicketEquipmentDetails.getStationCode());
//                    s=(SwAuInternetTicketEquipmentDetails)ObejctFieldsValueNotNull.setValueNoNull(SwAuInternetTicketEquipmentDetails.class,s);
//                    int ins= swAuInternetTicketEquipmentMapper.insertSwAuInputInternetTicketEquipmentDetail(s);
//                }
//            }

            if(swAuInternetTicketEquipment.getId()!=null){ //修改
                swAuInternetTicketEquipment.setUpdateTime(new Date());
                swAuInternetTicketEquipmentMapper.updateById(swAuInternetTicketEquipment);
            }else if(swAuInternetTicketEquipment.getId()==null){
                swAuInternetTicketEquipment.setCreatorId(UserInfo.getId());
                swAuInternetTicketEquipment.setCreatorName(UserInfo.getUserName());
                swAuInternetTicketEquipment.setCreateTime(new Date());
                swAuInternetTicketEquipment.setDelFlag("0");
                //swAuInternetTicketEquipment = (SwAuInternetTicketEquipment)ObejctFieldsValueNotNull.setValueNoNull(SwAuInternetTicketEquipment.class,swAuInternetTicketEquipment);
                swAuInternetTicketEquipmentMapper.insert(swAuInternetTicketEquipment);
            }
        }catch (Exception e){
            log.error("{}",e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new Exception(e.getMessage());
        }

        return 1;
    }

    /**
     * 互联网售票机数据详情
     * @param param
     * @return
     */
    public List<Map<String, Object>> getSwAuInputInternetTicketEquipmentDetails(Map<String,Object> param) {
        List<Map<String, Object>> res= swAuInternetTicketEquipmentMapper.getSwAuInputInternetTicketEquipmentDetails(param);
        return res;
    }

    /**
     * 互联网售票机数据录入审批
     * @param ids
     * @param chaYiIds
     * @return
     */
    public Integer approvePassSwAuInputInternetTicketEquipment(String ids,String chaYiIds) {
        UpdateWrapper<SwAuInternetTicketEquipment> updateWrapper=new UpdateWrapper<>();
        SwAuInternetTicketEquipment swAuInternetTicketEquipmentnew =new SwAuInternetTicketEquipment();
        swAuInternetTicketEquipmentnew.setApprovalStatus(1);
        updateWrapper.in("id",ids.split(","));
        swAuInternetTicketEquipmentMapper.update(swAuInternetTicketEquipmentnew, updateWrapper);
        //差异金额为0的ids
        Integer res= swAuInternetTicketEquipmentMapper.approvePassSwAuInputInternetTicketEquipment(chaYiIds.split(","));
        return res;
    }

    public void export(String ids, SwAuInternetTicketEquipment params, HttpServletResponse response) {
        List<SwAuInternetTicketEquipmentDto> records = new ArrayList<>();
        if(ids == null || ids.isEmpty()) {
            List<Map<String, Object>> res = tvmXianJinCengJiCYDXCService.getSwAuInputInternetTicketEquipmentList(params);
            records = getMapList(res);
        }else {
            List<Map<String, Object>> res = tvmXianJinCengJiCYDXCService.getSwAuInputInternetTicketEquipmentIdsList(ids.split(","));
            records = getMapList(res);
        }
        InputStream excelTemplateIs = null;
        try {response.reset(); // 非常重要
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            final String fileName = URLEncoder.encode("互联网售票机协查导出", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + System.currentTimeMillis() + ".xlsx");

            // 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
            // {} 代表普通变量 {.} 代表是list的变量

            excelTemplateIs = this.getClass().getResourceAsStream("/static/excel/export/SwAuInternetTicketEquipmentExcelTemplate.xlsx");

            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).registerConverter(new LocalDateTimeConverter()).registerConverter(new LocalDateConverter()).withTemplate(excelTemplateIs).build();
            WriteSheet writeSheet = EasyExcel.writerSheet("互联网售票机协查导出").build();
            // 这里注意 入参用了forceNewRow 代表在写入list的时候不管list下面有没有空行 都会创建一行，然后下面的数据往后移动。默认 是false，会直接使用下一行，如果没有则创建。
            // forceNewRow 如果设置了true,有个缺点 就是他会把所有的数据都放到内存了，所以慎用
            // 简单的说 如果你的模板有list,且list不是最后一行，下面还有数据需要填充 就必须设置 forceNewRow=true 但是这个就会把所有数据放到内存 会很耗内存
            // 如果数据量大 list不是最后一行 参照另一个
            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.FALSE).build();
            excelWriter.fill(records, fillConfig, writeSheet);

            excelWriter.finish();

        } catch (Exception e) {
            e.printStackTrace();
            log.error("互联网售票机协查导出失败");
        } finally {
            if(excelTemplateIs != null){
                try {
                    excelTemplateIs.close();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
        }
    }


    /**
     * 组织数据
     * @param res
     * @return
     */
    private List<SwAuInternetTicketEquipmentDto> getMapList(List<Map<String, Object>> res) {
        List<SwAuInternetTicketEquipmentDto> records = new ArrayList<>();

        for (int i = 0; i < res.size(); i++) {
            Map<String, Object> map = res.get(i);
            SwAuInternetTicketEquipmentDto swAuInternetTicketEquipmentDto = new SwAuInternetTicketEquipmentDto();
            swAuInternetTicketEquipmentDto.setRevenueDate(DateFormat.StringTurnLocalDate(map.get("revenueDate").toString()));
            swAuInternetTicketEquipmentDto.setLineName((String) map.get("line_name"));
            swAuInternetTicketEquipmentDto.setStationName((String) map.get("station_name"));
            swAuInternetTicketEquipmentDto.setEquipmentCode(String.valueOf(map.size() > 0 ? map.get("equipmentCode") : ""));


            Integer compareTotalNumberSales = 0;//发售数量
            BigDecimal compareSubtotalTotal = new BigDecimal(0);//发售金额
            if (map.get("compareTotalNumberSales") != null) {
                compareTotalNumberSales = (Integer) map.get("compareTotalNumberSales");
                swAuInternetTicketEquipmentDto.setCompareTotalNumberSales(compareTotalNumberSales);//发售数量
            }else {
                swAuInternetTicketEquipmentDto.setCompareTotalNumberSales(compareTotalNumberSales);
            }
            if (map.get("compareSubtotalTotal") != null) {
                compareSubtotalTotal = ((BigDecimal) map.get("compareSubtotalTotal")).divide(new BigDecimal(100));
                swAuInternetTicketEquipmentDto.setCompareSubtotalTotal(compareSubtotalTotal);//发售金额
            }else {
                swAuInternetTicketEquipmentDto.setCompareSubtotalTotal(compareSubtotalTotal);//发售金额
            }

            Integer totalNumberSales_cz = 0;//车站发售数量
            BigDecimal subtotalTotal_cz = new BigDecimal(0);//车站发售金额
            if (map.get("totalNumberSales") != null) {
                totalNumberSales_cz = (Integer) (map.get("totalNumberSales"));
                swAuInternetTicketEquipmentDto.setTotalNumberSales(totalNumberSales_cz);//车站发售数量
            }else {
                swAuInternetTicketEquipmentDto.setTotalNumberSales(totalNumberSales_cz);
            }
            if (map.get("subtotalTotal") != null) {
                subtotalTotal_cz = ((BigDecimal) map.get("subtotalTotal")).divide(new BigDecimal(100));
                swAuInternetTicketEquipmentDto.setSubtotalTotal(subtotalTotal_cz);//车站发售金额
            }else {
                swAuInternetTicketEquipmentDto.setSubtotalTotal(subtotalTotal_cz);
            }

            swAuInternetTicketEquipmentDto.setDiffSales(compareTotalNumberSales - totalNumberSales_cz);
            swAuInternetTicketEquipmentDto.setDiffAmount(compareSubtotalTotal.subtract(subtotalTotal_cz));
            swAuInternetTicketEquipmentDto.setDiffReason(String.valueOf(map.get("diffReason")));

            //确认数量
            swAuInternetTicketEquipmentDto.setConfirmNumber((Integer) map.get("confirmNumber"));
            //确认金额
            swAuInternetTicketEquipmentDto.setConfirmAmount(((BigDecimal) map.get("confirmAmount")).divide(new BigDecimal(100)));
            swAuInternetTicketEquipmentDto.setQueation("");
            records.add(swAuInternetTicketEquipmentDto);
        }
        return records;
    }
}
